# 使用正则表达式提取内容的类
# by lw 2023-11-09
import re
from typing import List, Optional


class RegMatch:

    def __init__(self):
        self.regs = [
            # 网络类的正则表达式：
            {
                'reg_name': 'email',
                'reg': r'[a-z0-9\.\-+_]+@[a-z0-9\.\-+_]+\.[a-z]+',
                'reg_desc': '提取电子邮件地址',
                'index': 0
            },
            {
                'reg_name': 'url',
                'reg': r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+',
                'reg_desc': '提取URL',
                'index': 0
            },
            {
                'reg_name': 'html_tag',
                'reg': r"<([^>]+)>",
                'reg_desc': 'HTML标签',
                'index': 0
            },
            {
                'reg_name': 'ipv4',
                'reg':
                r'((25[0-5]|2[0-4]\d|[01]?\d{1,2})\.){3}(25[0-5]|2[0-4]\d|[01]?\d{1,2})',
                'reg_desc': '提取IP地址',
                'index': 0
            },
            {
                'reg_name': 'ipv6',
                'reg': r'^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$',
                'reg_desc': '提取IP地址',
                'index': 0
            },
            # 电话类的正则表达式：
            {
                'reg_name': 'phone',
                'reg': r'\b\d{3}-\d{8}\b',
                'reg_desc': '提取电话号码',
                'index': 0
            },
            {
                'reg_name': 'mobile',
                'reg': r'\b1[3-9]\d{9}\b',
                'reg_desc': '提取手机号码',
                'index': 0
            },
            # 数字类的正则表达式：
            {
                'reg_name': 'amount',
                'reg': r'\d+(\.\d{1,2})?',
                'reg_desc': '提取金额',
                'index': 0
            },
            {
                'reg_name': 'number',
                'reg': r'\d+',
                'reg_desc': '提取整数',
                'index': 0
            },
            {
                'reg_name': 'fraction',
                'reg': r'\d+/\d+',
                'reg_desc': '提取分数',
                'index': 0
            },
            {
                'reg_name': 'decimal',
                'reg': r'\d+\.\d+',
                'reg_desc': '提取小数',
                'index': 0
            },
            # 日期时间类的正则表达式：
            {
                'reg_name': 'date',
                'reg': r'\b\d{4}-\d{2}-\d{2}\b',
                'reg_desc': '提取日期（YYYY-MM-DD）',
                'index': 0
            },
            {
                'reg_name': 'time',
                'reg': r'\b\d{2}:\d{2}:\d{2}\b',
                'reg_desc': '提取时间（HH:MM:SS）',
                'index': 0
            },
            {
                'reg_name': 'datetime',
                'reg': r'\b\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\b',
                'reg_desc': '提取日期时间（YYYY-MM-DD HH:MM:SS）',
                'index': 0
            },
            # 个人信息类的正则表达式：
            {
                'reg_name': 'pid',
                'reg':
                r'[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}[0-9Xx]',
                'reg_desc': '身份证号码',
                'index': 0
            },
            # 流通类的正则表达式：
            {
                'reg_name': 'postcode',
                'reg': r'\d{6}',
                'reg_desc': '提取中国邮政编码',
                'index': 0
            }
        ]

    def get_reg_index(self) -> List[dict]:
        """
        获取所有正则表达式的名称和索引

        Returns:
            list: 包含正则表达式名称和索引的列表
        """
        return self.regs

    def get(self, text: str, reg_name: str) -> Optional[str]:
        """
        在给定的文本中提取指定正则表达式的第一个匹配项

        Args:
            text (str): 要搜索的文本
            reg_name (str): 要匹配的正则表达式名称

        Returns:
            str: 第一个匹配项，如果没有匹配项则返回None
        """
        for reg in self.regs:
            if reg['reg_name'] == reg_name:
                match = re.search(reg['reg'], text)
                if match:
                    return match.group(reg['index'])
        return None

    def get_all(self, text: str, reg_name: str) -> List[str]:
        """
        在给定的文本中提取指定正则表达式的所有匹配项

        Args:
            text (str): 要搜索的文本
            reg_name (str): 要匹配的正则表达式名称

        Returns:
            list: 包含所有匹配项的列表，如果没有匹配项则返回空列表
        """
        results = []
        for reg in self.regs:
            if reg['reg_name'] == reg_name:
                matches = re.findall(reg['reg'], text)
                results.extend(matches)
        return results


# 示例用法
if __name__ == '__main__':
    matcher = RegMatch()
    text = "我的电子邮件是example@example.com，请给我发邮件。"
    email = matcher.get(text, 'email')
    print("提取到的电子邮件：", email)

    text = "请访问我的网站：https://www.example.com"
    url = matcher.get(text, 'url')
    print("提取到的URL：", url)

    text = "请拨打电话：028-12345678"
    phone = matcher.get(text, 'phone')
    print("提取到的电话号码：", phone)

    text = "请拨打手机：13812345678"
    mobile = matcher.get(text, 'mobile')
    print("提取到的手机号码：", mobile)

    text = "我的邮箱是example1@example.com和example2@example.com，请给我发邮件。"
    emails = matcher.get_all(text, 'email')
    print("提取到的所有电子邮件：", emails)

    text = "这本书的价格是99.99元。"
    amount = matcher.get(text, 'amount')
    print("提取到的金额：", amount)

    text = "这个分数是3/4。"
    fraction = matcher.get(text, 'fraction')
    print("提取到的分数：", fraction)

    text = "我的IP地址是192.168.0.1。"
    ip = matcher.get(text, 'ipv4')
    print("提取到的IP地址：", ip)

    text = "邮政编码是123456。"
    postcode = matcher.get(text, 'postcode')
    print("提取到的邮政编码：", postcode)
